
還記得 Day11 提到要取得即時資訊只能夠過 Function Calling 吧,網路上一堆教學都使用模擬資料,今天凱文大叔來教大家怎麼抓中央氣象局的資料吧
中央氣象局有個資料開放平台:https://opendata.cwa.gov.tw/index
註冊後就能在 會員資訊-取得授權碼 拿到自己的授權碼
可以在資料主題找需要的資料,由於我只要抓到目前的氣象資訊,所以選擇 觀測-現在天氣觀測報告
最好找有 API 的,不然需要下載檔案再用讀檔的方式處理

進入後就是 API 常用的 Swagger 網站了
點選 Try it out 輸入授權碼,按下 Execute 就能取得 JSon 資料了
上面那串URL就是我們要在程式中呼叫的 API,接下來看程式如何撰寫吧
Function<Request, Response> 的 Service,這隻程式就是要去氣象開放資料平台取得 Json 資料的類別@Service
public class WeatherService implements Function<WeatherService.Request, WeatherService.Response>{
    private final RestTemplate restTemplate;  //呼叫API的物件
    private final String apiUrl = "https://opendata.cwa.gov.tw/api/v1/rest/datastore/O-A0003-001";
    @Value("${CWA_API_KEY}")
    private String apiKey;
    
    public WeatherService(RestTemplateBuilder restTemplateBuilder) {
        this.restTemplate = restTemplateBuilder.build();
    }
    
	public JsonNode getFullWeatherData() {
		String fullUrl = apiUrl + "?Authorization=" + apiKey;
        try {
		        //直接將API結果轉成Json物件
            JsonNode response = restTemplate.getForObject(fullUrl, JsonNode.class);
            return response;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
	
	@Override
	public Response apply(Request request) {
		return new Response(getFullWeatherData());
	}
	public record Request(String State){  //這裡的Request參數其實沒任何作用
	}
	public record Response(JsonNode currWehther) {  //將所有的Json內容傳回,讓AI自行解析
	}
}
由於氣象局的Json內容太複雜,我們也不容易取得各個站點名稱,所以就不帶入任何參數,直接將所有的內容返回
@Configuration
@RequiredArgsConstructor
public class AiConfig {	
	@Autowired
	private WeatherService weatherService;
	@Bean
    public FunctionCallback currectWeather() {
        return FunctionCallbackWrapper.builder(weatherService)
                .withName("CurrectWeather")
                .withDescription("Get Currect Weather")
                .build();
    }
}
@RestController
@RequiredArgsConstructor
public class FunctionCallingController {
    private final ChatModel chatModel;
    @GetMapping("/func")
    public String func(String prompt) {        
        return chatModel.call(new Prompt(prompt, 
				                         OpenAiChatOptions.builder()
				                         .withFunction("CurrectWeather")
				                         .build())
        		).getResult().getOutput().getContent();
    }
}


可以看到 AI 不只是呼叫 Function 取得資料,還能幫我們進行統計分析,不過還是要注意一下,氣象局的原始資料非常大,很容易超過每次傳送的 Token 上限,若能做一些篩選在送出除了能避免錯誤外也能讓資料更為精準
今天學到的內容:
可以將瑣碎的內容處理交給 AI 處理
今日的程式碼: https://github.com/kevintsai1202/SpringBoot-AI-Day31.git
凱文大叔使用 Java 開發程式超過 20 年,對於 Java 生態非常熟悉,曾使用反射機制開發 ETL 框架,對 Spring 背後的原理非常清楚,目前以 Spring Boot 作為後端開發框架,前端使用 React 搭配 Ant Design
下班之餘在 Amazing Talker 擔任程式語言講師,並獲得學員的一致好評
最近剛成立一個粉絲專頁-凱文大叔教你寫程式 歡迎大家多追蹤,我會不定期分享實用的知識以及程式開發技巧
想討論 Spring 的 Java 開發人員可以加入 FB 討論區 Spring Boot Developer Taiwan
我是凱文大叔,歡迎一起加入學習程式的行列